package upload

import (
	"bytes"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"time"

	"sieve_admin_server_userpass/pkg/aliyun/oss"
	"sieve_admin_server_userpass/pkg/app"
	"sieve_admin_server_userpass/pkg/config"
	"sieve_admin_server_userpass/pkg/im3/chatmsg"
	"sieve_admin_server_userpass/pkg/im3/crypto"
	"sieve_admin_server_userpass/pkg/util/rand"
)

const (
	accessKeyId     = "LTAIJK7sdXrmBs3r"
	accessKeySecret = "p6hLVxR9NGfpGEsqych6I0ya9AFpID"
	endpoint        = "oss-cn-shenzhen.aliyuncs.com"
	bucket          = "imimages"
	domain          = "https://im.file.manyji.net"
)

var UPLOAD_FILE_SPLIT_SIZE int64 = 1024 * 1024

func init() {
	app.OnStart(init_oss)
	config.OnReload(init_oss)
}

func init_oss() {
	oss.SetAccessKey(accessKeyId, accessKeySecret)
	oss.SetBucket(endpoint, bucket)
}

func oss_Upload(name string, r io.Reader) (*chatmsg.UploadInfo, error) {
	upfile := &chatmsg.UploadInfo{
		Url:      []string{},
		Pwd:      rand.RandStr(32),
		FileName: name,
		FileSize: 0,
	}
	now := time.Now()
	date := now.Format("2006-01-02")
	ms := strconv.FormatInt(now.UnixNano()/int64(time.Millisecond), 10)
	splitname := "im/files/" + date + "/" + ms + crypto.MD5(name) + "_"
	size := UPLOAD_FILE_SPLIT_SIZE
	buf := bytes.NewBuffer([]byte{})
	i := 0
	for {
		i++
		buf.Reset()
		n, err := io.CopyN(buf, r, size)
		if err != nil && err != io.EOF {
			return nil, err
		}
		if n > 0 {
			b, err := crypto.AesEncrypt_bytes(upfile.Pwd, buf.Bytes())
			if err != nil {
				return nil, err
			}
			fname := splitname + strconv.Itoa(i)
			if err := oss.UploadBytes(fname, b); err != nil {
				return nil, err
			}
			upfile.Url = append(upfile.Url, domain+"/"+fname)
			upfile.FileSize += n
		}
		if err == io.EOF {
			break
		}
	}
	return upfile, nil
}

func OSS_UploadFile(file string) (*chatmsg.UploadInfo, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	return oss_Upload(filepath.Base(file), f)
}

func OSS_UploadBytes(name string, data []byte) (*chatmsg.UploadInfo, error) {
	r := bytes.NewReader(data)
	return oss_Upload(name, r)
}
